
#import <QuartzCore/QuartzCore.h>
#import "FindLampViewController.h"
#import "ChooseEffectViewController.h"
#import "lampmeta.h"
#import "CustomNavigationBar.h"
#import "DocumentViewController.h"
#import "UINavigationItem+Customization.h"
#import "HelpViewController.h"
#import "Data.h"
#import "InformationCell.h"
#import "NSString+VoiceOver.h"

@interface FindLampViewController () <InformationCellDelegate>

@end

@implementation FindLampViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    lampList = [[Data sharedInstance] lampList];
    
    self.pageControl.numberOfPages = lampList.count;
    
    UIButton *infoButton = [[UIButton alloc] initWithFrame:CGRectZero];
    [infoButton setImage:[UIImage imageNamed:@"btn-info-off.png"] forState:UIControlStateNormal];
    [infoButton setImage:[UIImage imageNamed:@"btn-info-on.png"] forState:UIControlStateHighlighted];
    [infoButton setImage:[UIImage imageNamed:@"btn-info-on.png"] forState:UIControlStateSelected];
    [infoButton sizeToFit];
    [infoButton addTarget:self action:@selector(showInfo) forControlEvents:UIControlEventTouchUpInside];
    
    UIBarButtonItem *infoBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
    infoBarButtonItem.accessibilityLabel = @"Hjälp";
    self.navigationItem.rightBarButtonItem = infoBarButtonItem;
    
    self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]];
    
    visiblePages = [NSMutableSet set];
    recycledPages = [NSMutableSet set];
    
    [self tileSinglePages];
    
    self.captionLabel.text = lampList[self.pageControl.currentPage][kLampItemCaption];
    
    [self.navigationItem customizeTitleInNavigationBarWithHeight:self.navigationController.navigationBar.frame.size.height];
    
    [self.pageControl addTarget:self action:@selector(valueChangedForPageControl:) forControlEvents:UIControlEventValueChanged];

    if (voiceoverEnabled) {
        UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bg"]];
        [bgImageView setFrame:self.accessibilityTableView.bounds];
        self.accessibilityTableView.backgroundView = bgImageView;
        self.accessibilityTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        self.accessibilityTableView.hidden = NO;
        [self.accessibilityTableView setContentInset:UIEdgeInsetsMake(22,0,22,0)];
        self.pageControl.accessibilityElementsHidden = YES;
    }
}

- (void)viewDidUnload
{
    [self setSingleScrollView:nil];
    [self setCaptionLabel:nil];
    [self setAccessibilityTableView:nil];
    [super viewDidUnload];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
     self.singleScrollView.clipsToBounds = NO;
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    self.singleScrollView.clipsToBounds = YES;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Scroll View Delegate Methods
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (!pageControlIsChangingPage) {
        NSInteger currentPage = self.currentPageForPageControl;
        if (currentPage < lampList.count &&
            self.pageControl.currentPage != currentPage) {
            self.pageControl.currentPage = currentPage;
        }
    }
    [self tileSinglePages];
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    self.pageControl.userInteractionEnabled = YES;
    if (pageControlIsChangingPage) {
        [self updateCaptionLabel];
    }
    pageControlIsChangingPage = NO;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self updateCaptionLabel];
}

#pragma mark -
- (void)updateCaptionLabel
{
    if ([self.captionLabel.text isEqualToString:lampList[self.pageControl.currentPage][kLampItemCaption]]) {
        return; // Don't update if label hasn't changed
    }
    
    [UIView animateWithDuration:0.15 animations:^{
        self.captionLabel.alpha = .2;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.15 animations:^{
            self.captionLabel.text = lampList[self.pageControl.currentPage][kLampItemCaption];
            self.captionLabel.alpha = 1;
        }];
    }];
}

- (IBAction)valueChangedForPageControl:(id)sender
{
    CGRect frame = self.singleScrollView.frame;
    frame.origin.x = frame.size.width * self.pageControl.currentPage;
    frame.origin.y = 0;
        
    self.pageControl.userInteractionEnabled = NO;
    [self.singleScrollView scrollRectToVisible:frame animated:YES];
    pageControlIsChangingPage = YES;
}

- (NSInteger)currentPageForPageControl
{
    UIScrollView *scrollView = self.singleScrollView;
    CGFloat pageWidth = scrollView.frame.size.width;
    return floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;   
}

- (BOOL)isDisplayingSinglePageForIndex:(NSInteger)index
{
    for (SinglePageView *page in visiblePages) {
        if (page.index == index) {
            return YES;
        }
    }
    return NO;
}

- (SinglePageView *)dequeueRecycledPage
{
    SinglePageView *page = [recycledPages anyObject];
    if (page) {
        [recycledPages removeObject:page];
    }
    return page;
}

- (CGRect)frameForSinglePageAtIndex:(NSInteger)index
{
    CGSize pageSize = self.singleScrollView.bounds.size;
    return CGRectMake(index*pageSize.width, 0, pageSize.width, pageSize.height);
}

- (void)addSinglePageWithIndex:(int)index
{
    SinglePageView *page = [self dequeueRecycledPage];
    if (!page) {
        page = [[SinglePageView alloc] initWithFrame:[self frameForSinglePageAtIndex:index]];
        page.delegate = self;
    } else {
        page.frame = [self frameForSinglePageAtIndex:index];
    }
    NSDictionary *currentLamp = lampList[index];
    page.index = index;
    page.image = [UIImage imageNamed:currentLamp[kLampItemImage]];
    
    [self.singleScrollView addSubview:page];
    [visiblePages addObject:page];
}

- (int)currentSinglePageIndex 
{
    return (int)((self.singleScrollView.contentOffset.x / self.singleScrollView.bounds.size.width));
}

- (void) resizeSingleScrollViewContentSize 
{
    self.singleScrollView.contentSize = CGSizeMake(self.singleScrollView.bounds.size.width * ([self currentSinglePageIndex]+2),
                                                   self.singleScrollView.bounds.size.height);
}

- (void)showInfo
{
    HelpViewController *helpVC = [[HelpViewController alloc] initWithNibName:nil bundle:nil];
    helpVC.documentFile = _(@"Socket");
    helpVC.title = _(@"Hjälp");
    [self presentModalViewController:helpVC animated:YES];
}

#define kHistoryCountForSinglePages 5
- (void) tileSinglePages
{
    CGRect visibleBounds = self.singleScrollView.bounds;
    int firstNeededSinglePageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
    int lastNeededSinglePageIndex  = floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds));
    firstNeededSinglePageIndex = MAX(0, firstNeededSinglePageIndex - kHistoryCountForSinglePages);
    lastNeededSinglePageIndex  = MAX(1, lastNeededSinglePageIndex + 1);
    
    // Recycle unneeded views
    for (SinglePageView *page in visiblePages) {
        if (page.index < firstNeededSinglePageIndex || page.index > lastNeededSinglePageIndex) {
            [recycledPages addObject:page];
            [page removeFromSuperview];
        }
    }
    [visiblePages minusSet:recycledPages];
    
    if (lastNeededSinglePageIndex < lampList.count) {
        // Add missing pages
        for (int i = firstNeededSinglePageIndex; i <= lastNeededSinglePageIndex; i++) {
            if (![self isDisplayingSinglePageForIndex:i]) {
                [self addSinglePageWithIndex:i];
            }
        }
        [self resizeSingleScrollViewContentSize];
    }

    // Cover flow view rotation
    static CGFloat kMaxRotation = 0.8 * M_PI_4;
    CGFloat viewWidth_2 = self.singleScrollView.frame.size.width / 2;
    for (SinglePageView *page in visiblePages) {
        CGFloat visualCenter = self.singleScrollView.contentOffset.x + viewWidth_2;
        CGFloat delta = page.center.x - visualCenter;
        if (ABS(delta) < 320) {
            CGFloat angle =  -kMaxRotation * delta / 160;
            
            CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
            rotationAndPerspectiveTransform.m34 = 2.0 / -500;
            rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, angle, 0.0f, 1.0f, 0.0f);
            
            page.layer.transform = rotationAndPerspectiveTransform;
        }
    }
}

#pragma mark - Single Page View Delegate
- (void)didTapOnSinglePageWithIndex:(NSUInteger)index
{
    NSDictionary *currentLamp = lampList[index];
    
    if (currentLamp[kLampItemEffects]) {
        ChooseEffectViewController *cEVC = [[ChooseEffectViewController alloc] initWithNibName:nil bundle:nil];
        cEVC.lampItem = currentLamp;
        [self.navigationController pushViewController:cEVC animated:YES];
        
    } else if (currentLamp[kLampItemDocument]) {
        DocumentViewController *detailVC = [[DocumentViewController alloc] initWithNibName:nil bundle:nil];
        [detailVC showDocumentWithName:currentLamp[kLampItemDocument]];
        detailVC.backButtonTitle = _(@"Välj lampa");
        detailVC.title = currentLamp[@"caption"];
        [self.navigationController pushViewController:detailVC animated:YES];
    }
}

#pragma mark - Table view datasource
#define kNibName @"InformationCell"
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return lampList.count;
}

static CGFloat cellHeight = 0; // Static because height does not change
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (!cellHeight) {
        UITableViewCell *cell = [[NSBundle mainBundle] loadNibNamed:kNibName owner:self options:nil][0];
        cellHeight = cell.frame.size.height;
    }
    return cellHeight;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    InformationCell *cell = (InformationCell *)[tableView dequeueReusableCellWithIdentifier:kNibName];
    if (!cell) {
        cell = [[NSBundle mainBundle] loadNibNamed:kNibName owner:self options:nil][0];
        cell.delegate = self;
    }
	cell.tag = indexPath.row;
    cell.titleLabel.text = lampList[indexPath.row][kLampItemCaption];
    cell.titleLabel.accessibilityLabel = [cell.titleLabel.text stringByOptimizingForVoiceOver];
    
	return cell;
}

-(void)informationCellPressedWithTag:(NSInteger)tag
{
    NSDictionary *currentLamp = lampList[tag];
    
    if (currentLamp[kLampItemEffects]) {
        ChooseEffectViewController *cEVC = [[ChooseEffectViewController alloc] initWithNibName:nil bundle:nil];
        cEVC.lampItem = currentLamp;
        [self.navigationController pushViewController:cEVC animated:YES];
        
    } else if (currentLamp[kLampItemDocument]) {
        DocumentViewController *detailVC = [[DocumentViewController alloc] initWithNibName:nil bundle:nil];
        [detailVC showDocumentWithName:currentLamp[kLampItemDocument]];
        detailVC.backButtonTitle = _(@"Välj lampa");
        detailVC.title = currentLamp[@"caption"];
        [self.navigationController pushViewController:detailVC animated:YES];
    }
}


@end
